package org.nlp2rdf.navigator.component.resource.maps;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.nlp2rdf.navigator.client.exception.NKEQueryException;
import org.nlp2rdf.navigator.component.exception.ComponentInitException;
import org.nlp2rdf.navigator.refactored.SparqlService;

import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSetRewindable;

public class MapWithSparql extends AbstractMap implements IMap {
	private static final Logger logger = Logger.getLogger(MapWithSparql.class);

	private static final String VARIABLE = "what";
	SparqlService sparqlService;
	String language = null;
	String property = null;

	@Override
	protected void _init() throws ComponentInitException {
		// do nothing
	}

	@Override
	public Map<String, String> getMap(Set<String> keys) throws NKEQueryException {
		check();
		Map<String, String> ret = new HashMap<String, String>();
		String retrieved = null;
		for (String uri : keys) {
			try {
				// don't put empty values in there
				if ((retrieved = retrieve(uri)) != null) {
					ret.put(uri, retrieved);
				}
			} catch (Exception e) {
				logger.error("something went wrong " + uri, e);
			}

		}
		return ret;
	}

	private String retrieve(String uri) throws NKEQueryException {

		if (uri == null) {
			logger.error("URI was null in MapWithSparql");
			return null;
		} else if (uri.equals("Thing")) {
			return null;
		}

		String filter = "";
		if (language != null) {
			filter = " FILTER (lang(?" + VARIABLE + ") = \"" + language + "\") . ";
		}
		String query = "SELECT ?" + VARIABLE + " {<" + uri + "> <" + property + "> ?" + VARIABLE + " . "
				+ filter + "} Limit 1 ";

		ResultSetRewindable rsw = sparqlService.queryAsResultSet(query);

		if (!rsw.hasNext()) {
			logger.warn("Getting label/comments failed " + query);
			return null;
		} else {
			QuerySolution s = rsw.nextSolution();
			try {
				return s.getLiteral(VARIABLE).getLexicalForm();
			} catch (Exception e) {
				logger.warn("retrieving literal failed somehow" + s);
				return null;
			}
		}

	}

	public void setSparqlService(SparqlService sparqlService) {
		this.sparqlService = sparqlService;
	}

	public void setLanguage(String language) {
		this.language = language;
	}

	public void setProperty(String property) {
		this.property = property;
	}

}
